<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html><head><title>Programming in Lua : 21.2</title>
<link rel="stylesheet" type="text/css" href="pil.css">
</head>
<body>
<p class="warning">
<A HREF="contents.html"><IMG TITLE="Programming in Lua (first edition)" SRC="capa.jpg" ALT="" ALIGN="left"></A>This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.<BR>The third edition targets Lua 5.2 and is available at <A HREF="http://www.amazon.com/exec/obidos/ASIN/859037985X/theprogrammil3-20">Amazon</A> and other bookstores.<BR>By buying the book, you also help to <A HREF="../donations.html">support the Lua project</A>.
</p>
<table width="100%" class="nav">
<tr>
<td width="10%" align="left"><a href="21.1.html"><img border="0" src="left.png" alt="Previous"></a></td>
<td width="80%" align="center"><a href="contents.html"><font face="Helvetica,Arial,sanserif">
<font color="gray">Programming in </font><font color="blue"> Lua</font>
</font></a></td>
<td width="10%" align="right"><a href="21.2.1.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
<tr>
<td width="10%" align="left"></td>
<td width="80%" align="center"><a href="contents.html#P3">Part III. The Standard Libraries</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="contents.html#21">Chapter 21. The I/O Library</a></td>
<td width="10%" align="right"></td></tr>
</table>
<hr/>
<p><h2>21.2 &ndash; The Complete I/O Model</h2>

<p>For more control over I/O,
you can use the complete model.
A central concept in this model is the <em>file handle</em>,
which is equivalent to streams (<code>FILE*</code>) in C:
It represents an open file with a current position.

<p>To open a file, you use the <code>io.open</code> function,
which mimics the <code>fopen</code> function in C.
It receives as arguments the name of the file to open
plus a <em>mode</em> string.
That mode string may contain an `<code>r</code>&acute; for reading,
a `<code>w</code>&acute; for writing (which also erases any previous content of the file),
or an `<code>a</code>&acute; for appending,
plus an optional `<code>b</code>&acute; to open binary files.
The <code>open</code> function returns a new handle for the file.
In case of errors, <code>open</code> returns <B>nil</B>,
plus an error message and an error number:
<pre>
    print(io.open("non-existent file", "r"))
      --> nil     No such file or directory       2
    
    print(io.open("/etc/passwd", "w"))
      --> nil   Permission denied       13
</pre>
The interpretation of the error numbers is system dependent.

<p>A typical idiom to check for errors is
<pre>
    local f = assert(io.open(filename, mode))
</pre>
If the <code>open</code> fails,
the error message goes as the second argument to <code>assert</code>,
which then shows the message.

<p>After you open a file,
you can read from it or write to it
with the methods <code>read</code>/<code>write</code>.
They are similar to the <code>read</code>/<code>write</code> functions,
but you call them as methods on the file handle,
using the colon syntax.
For instance, to open a file and read it all,
you can use a chunk like this:
<pre>
    local f = assert(io.open(filename, "r"))
    local t = f:read("*all")
    f:close()
</pre>

<p>The I/O library also offers handles for the three predefined C streams:
<code>io.stdin</code>, <code>io.stdout</code>, and <code>io.stderr</code>.
So, you can send a message directly to the error stream
with a code like this:
<pre>
    io.stderr:write(message)
</pre>

<p>We can mix the complete model with the simple model.
We get the current input file handle
by calling <code>io.input()</code>, without arguments.
We set the current input file handle
with the call <code>io.input(handle)</code>.
(Similar calls are also valid for <code>io.output</code>.)
For instance,
if you want to change the current input file temporarily,
you can write something like this:
<pre>
    local temp = io.input()   -- save current file
    io.input("newinput")      -- open a new current file
    ...                       -- do something with new input
    io.input():close()        -- close current file
    io.input(temp)            -- restore previous current file
</pre>

<hr/>
<table width="100%" class="nav">
<tr valign="top">
<td width="90%" align="left">
<small>
  Copyright &copy; 2003&ndash;2004 Roberto Ierusalimschy.  All rights reserved.
</small>
</td>
<td width="10%" align="right"><a href="21.2.1.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
</table>


</body></html>

